#include<pthread.h>
#include<iostream>
#include<unistd.h>
#include<string>
#include"RingQueue.hpp"
#include"TASK.hpp"

template<class T>
class ThreadData{
public:
    std::string name_;
    Ringqueue<Task<T>> *rq_;
};

void* consumer(void* args)
{

    //Ringqueue<Task<int>> *rq=static_cast<Ringqueue<Task<int>> *> (args);

    ThreadData<int>* td=static_cast<ThreadData<int>*> (args);
    Ringqueue<Task<int>>* rq=td->rq_;
    while(1)
    {
        //消费数据
        Task<int> re=rq->pop();

        //处理数据
        re();
        std::cout<<"My name:"<<td->name_<<";";
        re.getTask();
        sleep(1);
    }

    return nullptr;
}

void* producter(void* args)
{
    //Ringqueue<Task<int>> *rq=static_cast<Ringqueue<Task<int>> *> (args);
    ThreadData<int>* td=static_cast<ThreadData<int>*> (args);
    Ringqueue<Task<int>>* rq=td->rq_;
    while(1)
    {
        sleep(3);
        //获取数据
        int data1=rand()%10;
        int data2=rand()%10;
        char op=opers[rand()%opers.size()];
        Task<int> t(data1,data2,op);

        //生产数据
        std::cout<<"My name:"<<td->name_<<";"<<data1<<op<<data2<<"=?"<<std::endl;
        rq->push(t);
    }

    return nullptr;
}

int main()
{
    //单生产单消费
    // srand(time(nullptr)^(getpid()));
    // pthread_t c,p;
    // Ringqueue<Task<int>> *rq=new Ringqueue<Task<int>>();

    // pthread_create(&c,nullptr,consumer,rq);
    // pthread_create(&p,nullptr,producter,rq);

    // pthread_join(c,nullptr);
    // pthread_join(p,nullptr);

    srand(time(nullptr)^(getpid()));
    pthread_t c[3],p[5];
    Ringqueue<Task<int>> *rq=new Ringqueue<Task<int>>();

    for(int i=0;i<3;i++)
    {
        ThreadData<int>* td=new ThreadData<int>();
        td->name_="consumer"+std::to_string(i);
        td->rq_=rq;
        pthread_create(&c[i],nullptr,consumer,td);
    }
    for(int i=0;i<5;i++)
    {
        ThreadData<int>* td=new ThreadData<int>();
        td->name_="producter"+std::to_string(i);
        td->rq_=rq;
        pthread_create(&p[i],nullptr,producter,td);
    }

    for(int i=0;i<3;i++)
    {
        pthread_join(c[i],nullptr);
    }
    for(int i=0;i<5;i++)
    {
        pthread_join(p[i],nullptr);
    }

    return 0;
}
